import java.util.Arrays;

/**
 * 数组的创建和使用
 *
 * @author yinjw
 */
public class ArrayDemo {

    /**
     * 程序入口
     * @param args 启动参数
     */
    public static void main(String[] args) {
//        testArray();
        // 数组的创建和初始化并赋值
        int[] shuyunGrades = {90, 89, 92};
        testArrayWhile(shuyunGrades);

        System.out.println("====================");

        // 排序
        int[] array = {90, 89, 92, 80, 70};
        testBubbleSort(array);
        testArrayWhile(array);

        System.out.println("============");
        // 查找最大值
        int max = searchMax(array);
        System.out.println(max);

        System.out.println("========================");
        testBubbleSort(array);
        int search = testBinarySearch(array, 92);
        System.out.println(search);
    }

    /**
     * 演示数组的创建和使用
     */
    public static void testArray() {

        // 声明数组 type[] x;
        int[] grades;

        // 数组的初始化，必须要指定数组长度
        grades = new int[42];

        // 访问数组的每个元素 grades[0]
        System.out.println(grades[2]);

        // 给数组的元素赋值
        grades[0] = 90;
        grades[1] = 91;
        System.out.println(grades[1]);

        // 数组的创建和初始化并赋值
        int[] shuyunGrades = {90, 89, 92};

        // 获取数组的长度
        System.out.println(shuyunGrades.length);


    }

    /**
     * 数组的遍历
     */
    public static void testArrayWhile(int[] array) {
        // for循环
//        for (int i = 0; i < array.length; i++) {
//            System.out.println("第" + (i+1) + "的成绩是：" + array[i]);
//        }

        // 增强for循环
        for (int item : array) {
            System.out.println(item);
        }
    }

    /**
     * 从小到大冒泡排序
     */
    public static void testBubbleSort(int[] array) {
        // 开始冒泡排序算法
        // 一共需要比较length-1轮
        for (int i = 0; i < array.length - 1; i++) {
            // 用来判断下一次是否有数据交换
            boolean flag = false;

            // 每一轮需要比较length-1-i轮
            for (int j = 0; j < array.length - 1 - i; j++) {
                if (array[j] > array[j+1]) {
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                    flag = true;
                }
            }

            // 如果没有数据交换，则提前结束冒泡排序
            if (!flag) {
                break;
            }
        }
    }

    /**
     * 查找最大值
     *
     * @param array 目标数组
     * @return 对应的最大值
     */
    public static int searchMax(int[] array) {
        // 默认最大值为第一个元素
        int max = array[0];
        for (int i = 1; i < array.length; i++) {
            //对比每一个元素的下一个元素是不是比当前元素大
            if (max < array[i]) {
                max = array[i];
            }
        }
        return max;
    }


     /**
     * 二分查找，前提：必须有序
     * 1.给定一个数组 ：1，8，18，19，20，21
     * 2.确定两个标记，初始下标为left 0，right length-1
     * 3.通过(left+right)/2 获取中间索引
     * 4.比较
     * 5.移动left或者right
     *
     * @param array     目标数组
     * @param target    要查询的目标值
     * @return  查到的下标
     */
    public static int testBinarySearch(int[] array, int target) {
        // 定义两个标记
        int left = 0;
        int right = array.length - 1;

        while (left <= right) {
            // 获取中间索引
            int mid = (left + right) / 2;

            // 比较
            if (array[mid] == target) {
                return mid;
            } else if (array[mid] > target) {
                right = mid - 1;
            } else if (array[mid] < target) {
                left = mid + 1;
            }
        }

        return -1;
    }
}
